
/* 
    1 更改v4l2config初始化配置文件;
    2 使用新的config.c文件 获取mipi grey数据
    3 使用mpp_buffer的api获取buf的 *ptr len，然后写入文件 
*/
#include "v4l2config.h"
#include <stdio.h>
#include <stdlib.h>
#include "bsp_encoder.h"
Uart_t* g_uart_mcu = nullptr;          // 串口上下文指针
pthread_mutex_t mcu_data_lock = PTHREAD_MUTEX_INITIALIZER;  //静态锁，针对串口mcu的串口；读数据保护，写数据保护

//2 laser
Uart_t* g_uart_laser = nullptr;          // 串口上下文指针
//3 红外
Uart_t* g_uart_icr = nullptr;          // 串口上下文指针
//4 可见
Uart_t* g_uart_vis = nullptr;          // 串口上下文指针
//5 镜头
Uart_t* g_uart_lens = nullptr;          // 串口上下文指针
//6 RS422传输数据口
Uart_t* g_uart_usb0 = nullptr;          // 串口上下文指针
pthread_mutex_t usb0_data_lock = PTHREAD_MUTEX_INITIALIZER;  //静态锁，针对串口usb0的串口；读数据保护，写数据保护

pthread_mutex_t select_video_lock = PTHREAD_MUTEX_INITIALIZER;  //静态锁，针对串口usb0的串口；读数据保护，写数据保护
int main() {

    // ==================== 1. 初始化编码器/摄像头 ====================

    MPP_Encoder* enc_ctx = Mpp_encoder_init(640, 480, 30, 20, MPP_FMT_YUV422_YUYV);
    if (!enc_ctx) {
        fprintf(stderr, "错误：编码器初始化失败\n");
        return -1;
    }
    // ==================== 2. 初始化 MPP 缓冲区 ====================
    MPP_RET ret = MPP_OK;

    // 获取缓冲区组
    ret = mpp_buffer_group_get_internal(&enc_ctx->buf_grp, MPP_BUFFER_TYPE_DRM);
    if (ret != MPP_OK) {
        fprintf(stderr, "错误：获取缓冲区组失败\n");
        Mpp_encoder_deinit(enc_ctx);
        return -1;
    }

    // 计算一帧 YUV420SP 数据大小（宽*高*1.5）
    size_t frame_size = 640 * 480 * 3 / 2;

    // 获取输入帧缓冲区
    ret = mpp_buffer_get(enc_ctx->buf_grp, &enc_ctx->frm_buf, frame_size);
    if (ret != MPP_OK) {
        fprintf(stderr, "错误：获取输入帧缓冲区失败\n");
        Mpp_encoder_deinit(enc_ctx);
        return -1;
    }

    // （可选）获取其他缓冲区（如编码输出、运动数据等，根据需求启用）
    // ret = mpp_buffer_get(enc_ctx->buf_grp, &enc_ctx->pkt_buf, frame_size);
    // if (ret != MPP_OK) { /* 错误处理 */ }


    // ==================== 3. 初始化 MPP 编码上下文 ====================
    ret = mpp_create(&enc_ctx->ctx, &enc_ctx->mpi);
    if (ret != MPP_OK) {
        fprintf(stderr, "错误：创建 MPP 上下文失败\n");
        Mpp_encoder_deinit(enc_ctx);
        return -1;
    }

    ret = mpp_init(enc_ctx->ctx, MPP_CTX_ENC, MPP_VIDEO_CodingAVC); // 编码类型设为 H.264
    if (ret != MPP_OK) {
        fprintf(stderr, "错误：初始化 MPP 上下文失败\n");
        Mpp_encoder_deinit(enc_ctx);
        return -1;
    }

    ret = mpp_enc_cfg_init(&enc_ctx->cfg);
    if (ret != MPP_OK) {
        fprintf(stderr, "错误：初始化编码配置失败\n");
        Mpp_encoder_deinit(enc_ctx);
        return -1;
    }

    ret = enc_ctx->mpi->control(enc_ctx->ctx, MPP_ENC_GET_CFG, enc_ctx->cfg);
    if (ret != MPP_OK) {
        fprintf(stderr, "错误：获取编码配置失败\n");
        Mpp_encoder_deinit(enc_ctx);
        return -1;
    }

    // （可选）配置编码参数（如码率、GOP 等）
    // mpp_enc_cfg_set_s32(enc_ctx->cfg, "rc:bitrate", 2000000); // 2Mbps 码率
    // mpp_enc_cfg_set_s32(enc_ctx->cfg, "rc:gop", 30);         // GOP 长度 30


    // ==================== 4. 采集并保存视频帧 ====================
    const int CAPTURE_FRAMES = 100; // 采集 100 帧

    for (int i = 0; i < CAPTURE_FRAMES; ++i) {
        // 采集一帧数据
        ret = mpp_run(enc_ctx, NULL, &enc_ctx->cam_frm_idx);
        if (ret != MPP_OK) {
            fprintf(stderr, "错误：采集第 %d 帧失败\n", i);
            break;
        }
    }

    printf("采集完成，共保存 %d 帧到 captured.yuv\n", CAPTURE_FRAMES);


    // ==================== 5. 释放资源 ====================
    Mpp_encoder_deinit(enc_ctx);
    printf("资源已释放\n");

    return 0;
}